
#ifndef __SERVER_PER_CPU_HPP__
#define __SERVER_PER_CPU_HPP__

#include "khan.hpp"
#include "io_service_pool.hpp"
#include "ipc_session.hpp"


template <typename SessionPtr, typename Manager>
class server_per_cpu 
: private boost::noncopyable
{
public:
    explicit server_per_cpu(std::size_t psize, Manager& manager, 
            const tcp::endpoint& ep)
        : _ioserv_pool(psize),
        _acceptor(_ioserv_pool.get_io_service(), ep),
        _manager(manager)
    {
        SessionPtr new_session =  
            _manager.create_session(_ioserv_pool.get_io_service());

        _acceptor.set_option(tcp_acceptor::reuse_address(true));
        _acceptor.async_accept(new_session->socket(),
                boost::bind(&server_per_cpu::handle_accept, this, new_session,
                    boost::asio::placeholders::error));
    }

    void run() { _ioserv_pool.run(); }
    void stop() { _ioserv_pool.stop(); }
    void handle_accept(SessionPtr session,
            const boost::system::error_code& error)
    {
        if (!error) {
            session->start();
            SessionPtr new_session =  
                _manager.create_session(_ioserv_pool.get_io_service());
            _acceptor.async_accept(new_session->socket(),
                    boost::bind(&server_per_cpu::handle_accept, this, new_session,
                        boost::asio::placeholders::error));
        }
        else {
            PDBG("exception: %s\n", error.message().c_str());
        }
    }

private:
    io_service_pool _ioserv_pool;
    tcp::acceptor _acceptor;
    Manager& _manager;
};

#endif  /* end __SERVER_PER_CPU_HPP__ */

